//
//  CMLanguage.swift
//  TTCOM
//
//  Created by Toj on 4/29/22.
//

import Foundation

public extension Notification.Name {
    static let CMLanguageDidChanged = Notification.Name("TTLanguageDidChanged")
}

public func TTLocalizedString(
    for key: String,
    default value: String? = nil,
    table name: String? = nil
) -> String {
    return CMLocalized.defalut.localized(for: key,
                                         default: value,
                                         table: name)
}

open class CMLocalized: NSObject {
    public static let `defalut` = CMLocalized()
    
    // CMLanguage.defaultLanguage zh-Hans.
    private var _current = ""
    public private(set) var current: String {
        set {
            _current = newValue
            userDefaults.set(newValue, forKey: TTCurrentLanguageKey)
            userDefaults.synchronize()
        }
        
        get {
            if _current.isEmpty {
                _current = userDefaults.string(forKey: TTCurrentLanguageKey) ?? defaultLanguage
            }
            return _current
        }
    }
    
    // 当前语言包资源
    private lazy var languageBundle: Bundle = {
        return englishBundle
    }()
    
    private let TTCurrentLanguageKey = "selected_Language_key"
    private let defaultLanguage = "en"
    private let userDefaults = UserDefaults.standard
    private let mainBundle = Bundle.main
    
    private lazy var englishBundle: Bundle = {
        let resourcePth = Bundle.main.path(forResource: defaultLanguage, ofType: "lproj") ?? ""
        let bundle = Bundle(path: resourcePth) ?? .main
        return bundle
    }()
}

public extension CMLocalized {
    
    /* 初始化语言包 */
    func setup() {
        // print("-->toj: current: " + current)
        
        // 如果没有设置当前语言, 获取app内支出的系统语言
        if current.isEmpty { current = prefsLanguage() }
        // 没有符合的语言, 给个默认值: "en"
        if current.isEmpty { current = defaultLanguage }
        
        // 初始化语言包资源
        guard let path = mainBundle.path(forResource: current, ofType: "lproj"),
              let bundle = Bundle(path: path) else {
            // 初始化语言失败, 默认语言包资源
            current = defaultLanguage
            languageBundle = englishBundle
            return
        }
        
        languageBundle = bundle
    }
    
    /* 清除语言缓存 */
    func clearCache() {
        current = ""
        setup()
    }
    
    /* 设置语言 */
    func setLanguage(_ language: String) {
        guard let path = mainBundle.path(forResource: language, ofType: "lproj"),
              let bundle = Bundle(path: path) else { return }
        
        current = language
        languageBundle = bundle
        
        var userInfo: [AnyHashable: Any] = [:]
        userInfo["language"] = language
        NotificationCenter.default.post(name: .CMLanguageDidChanged, object: nil, userInfo: userInfo)
    }
}

public extension CMLocalized {
    /*
     * app内支持系统的语言
     * 获取系统首选语言列表: Setting->通用->语言地区->首选语言,
     * NOTE: 只有一个语言不会显示首选语言列表
     */
    var preferredLanguages: [String] {
        return Locale.preferredLanguages
    }
    
    var localizations: [String] {
        return mainBundle.localizations
    }
    
    /* app首选语言 */
    func prefsLanguage() -> String {
        // 获取系统首选语言列表: Setting->通用->语言地区->首选语言,
        // NOTE: 只有一个语言不会显示首选语言列表
        let languages = preferredLanguages
        // app支持的语言
        let localizations = localizations
        var prefs = ""
        for language in languages {
            // print("-->toj: preferred: " + language)
            for localization in localizations {
                // print("-->toj: localization: " + localization)
                guard language.contains(localization) else { continue }
                prefs = localization
                break
            }
            
            guard !prefs.isEmpty else { continue }
            break
        }
        
        return prefs
    }
}

public extension CMLocalized {
    
    func localized(
        for key: String,
        default value: String? = nil,
        table name: String? = nil
    ) -> String {
        let localizeString = languageBundle.localizedString(forKey: key, value: value, table: name)
        return localizeString
    }
}
